package com.semidata.rtd.core.config;

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.Properties;

public abstract class Config {

    protected void initConfig(String configFile) {
        try {

            Properties properties = new Properties();
            try {
                properties.load(new FileInputStream(new File(configFile)));
            } catch (Exception e) {
                properties = new Properties();
            }
            
            Field[] fields = this.getClass().getDeclaredFields();

            for (Field field : fields) {
                Property annotation = field.getAnnotation(Property.class);
                if (annotation == null)
                    continue;

                String value = properties.getProperty(annotation.value());
                if (value == null) {
                    if (annotation.required()) {

                        DefaultValue defaultValueAnnotation = field.getAnnotation(DefaultValue.class);
                        if (defaultValueAnnotation != null) {
                            value = defaultValueAnnotation.value();
                        } else {
                            DefaultValueClass defaultValueClassAnnotation = field.getAnnotation(DefaultValueClass.class);
                            if (defaultValueClassAnnotation == null)
                                throw new Exception("field " + annotation.value() + " not exist");
                            value = defaultValueClassAnnotation.value().newInstance().value();
                        }

                    } else {
                        continue;
                    }
                }

                Class<?> type = field.getType();

                try {
                    field.setAccessible(true);
                    Handler handler = field.getAnnotation(Handler.class);
                    if (handler != null) {

                        field.set(this, handler.value().newInstance().handle(value));
                    } else {
                        if (type == Integer.class || type == int.class) {
                            field.set(this, Integer.parseInt(value));
                        } else if (type == Double.class || type == double.class) {
                            field.set(this, Double.parseDouble(value));
                        } else if (type == Long.class || type == long.class) {
                            field.set(this, Long.parseLong(value));
                        } else if (type == Float.class || type == float.class) {
                            field.set(this, Float.parseFloat(value));
                        } else if (type == Boolean.class || type == boolean.class) {
                            field.set(this, Boolean.parseBoolean(value));
                        } else if (type == String.class) {
                            field.set(this, value);
                        } else {
                            throw new Exception(type.getName() + "not supported");
                        }
                    }
                } catch (Exception e) {
                    throw e;
                } finally {
                    field.setAccessible(false);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
